﻿using RpcCacheClient.Interface;
using RpcSyncService.Interface;

namespace RpcSyncService.Accredit
{
    internal class AccreditKeySevice : IAccreditKeyCollect
    {
        private static readonly string _AccreditKey = "AccreditKey_";
        private readonly IRedisCache _Cache;

        public AccreditKeySevice(IRedisCache redis)
        {
            _Cache = redis;
        }
        public bool Renewal(IAccreditToken token, TimeSpan time)
        {
            string name = string.Concat(_AccreditKey, token.CheckKey);
            if (this._Cache.TryUpdate<Guid>(name, (a) =>
            {
                return a == token.AccreditId ? a : token.AccreditId;
            }, out Guid id, time))
            {
                if (id != token.AccreditId)
                {
                    token.Cancel();
                }
                return true;
            }
            return false;
        }
        public bool TryRemove(string checkKey, Guid accreditId)
        {
            string name = string.Concat(_AccreditKey, checkKey);
            return this._Cache.TryRemove<Guid>(name, (a) => a == accreditId);
        }
        public Guid? KickOut(string checkKey)
        {
            string name = string.Concat(_AccreditKey, checkKey);
            if (this._Cache.TryRemove(name, out Guid accreditId))
            {
                return accreditId;
            }
            return null;
        }
        public Guid Set(string applyKey, Guid accreditId, TimeSpan time)
        {
            string name = string.Concat(_AccreditKey, applyKey);
            return this._Cache.AddOrUpdate<Guid>(name, accreditId, (a, b) =>
            {
                return a != b ? b : a;
            }, time);
        }

        public bool Check(string checkKey, Guid accreditId)
        {
            string key = string.Concat(_AccreditKey, checkKey);
            if (!this._Cache.TryGet<Guid>(key, out Guid val))
            {
                return false;
            }
            return val == accreditId;
        }

    }
}
